package com.come4loves.game.module.battle.helper;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import com.come4loves.game.module.battle.model.ActorCard;
import com.come4loves.game.module.battle.model.BattleData;
import com.come4loves.game.module.card.constant.CardType;
import com.come4loves.game.module.fight.action.Action;
import com.come4loves.game.module.fight.action.AttackAction;
import com.come4loves.game.module.fight.action.AttributeChangeAction;
import com.come4loves.game.module.fight.action.BatchAction;
import com.come4loves.game.module.fight.action.BuffAction;
import com.come4loves.game.module.fight.action.CardToLocationAction;
import com.come4loves.game.module.fight.action.ChangeUnitAction;
import com.come4loves.game.module.fight.action.ChooseCardAction;
import com.come4loves.game.module.fight.action.EndAction;
import com.come4loves.game.module.fight.action.MagicChangeAction;
import com.come4loves.game.module.fight.action.MomentAction;
import com.come4loves.game.module.fight.action.SkillAction;
import com.come4loves.game.module.fight.constants.BuffType;
import com.come4loves.game.module.fight.constants.EndType;
import com.come4loves.game.module.fight.constants.FightMoment;
import com.come4loves.game.module.fight.constants.FighterAttribute;
import com.come4loves.game.module.fight.constants.Team;
import com.come4loves.game.module.fight.model.Card2Location;
import com.come4loves.game.module.fight.model.FightCard;
import com.come4loves.game.proto.BattleProto;
import com.come4loves.game.proto.BattleProto.CardsInfo;
import com.come4loves.game.proto.BattleProto.GeneralAct.ActionType;

public class PBConvertHelper {
	public static BattleProto.CardType cardTypeConvert(CardType type) {
		for (BattleProto.CardType cardType : BattleProto.CardType.values()) {
			if (type.ordinal() == cardType.ordinal()){
				return cardType;
			}
		}
		return BattleProto.CardType.CARD_TYPE_NONE;
	}
	public static CardType cardTypeReverse(BattleProto.CardType type) {
		for (CardType cardType : CardType.values()) {
			if (type.ordinal() == cardType.ordinal()){
				return cardType;
			}
		}
		return CardType.NONE;
	}
	
	public static BattleProto.Team teamConvert(Team team) {
		for (BattleProto.Team t : BattleProto.Team.values()) {
			if (t.ordinal() == team.ordinal()) {
				return t;
			}
		}
		return BattleProto.Team.TEAM_NONE;
	}
	
	public static BattleProto.FightMoment fightMomentConvert(FightMoment moment) {
		for (BattleProto.FightMoment m : BattleProto.FightMoment.values()) {
			if (m.ordinal() == moment.ordinal()) {
				return m;
			}
		}
		return BattleProto.FightMoment.NONE;
	}
	public static BattleProto.BuffType buffTypeConvert(BuffType type) {
		for (BattleProto.BuffType t : BattleProto.BuffType.values()) {
			if (t.ordinal() == type.ordinal()) {
				return t;
			}
		}
		return BattleProto.BuffType.BUFF_NONE;
	}
	public static BattleProto.CardToLocation cardLocationConvert(Card2Location location, boolean allInfo, Long actorId) {
		BattleProto.CardLocation cardLocation = BattleProto.CardLocation.OutsideGame;
		for (BattleProto.CardLocation cl : BattleProto.CardLocation.values()) {
			if (cl.ordinal() == location.getCardLocation().ordinal()) {
				cardLocation =  cl;
			}
		}
		BattleProto.CardToLocation.Builder builder = BattleProto.CardToLocation.newBuilder();
		builder.setCardInfo(fightCard2CardsInfo(location.getFightCard(), allInfo, actorId));
		builder.setLocation(cardLocation);
		builder.setTargetGeneral(location.getTarget());
		return builder.build();
		
	}
	
	public static BattleProto.CardsInfo fightCard2CardsInfo(FightCard fightCard, boolean allInfo, Long actorId){
			BattleProto.CardsInfo.Builder cardsInfoBuilder = BattleProto.CardsInfo.newBuilder();
			cardsInfoBuilder.setId(fightCard.getId());
			if (allInfo) {
				cardsInfoBuilder.setCfgId(fightCard.getCfgId());
				cardsInfoBuilder.setAttack(fightCard.getAttack());
				cardsInfoBuilder.setHp(fightCard.getHp());
				cardsInfoBuilder.setMagic(fightCard.getMagic());
				cardsInfoBuilder.setSpeed(fightCard.getSpeed());
				cardsInfoBuilder.setType(PBConvertHelper.cardTypeConvert(fightCard.getCardType()));
			}
			if (actorId != null) {
				cardsInfoBuilder.setActorId(actorId);
			}
			return cardsInfoBuilder.build();
	}
	public static List<BattleProto.CardsInfo> fightCard2CardsInfo(Collection<FightCard> cardList, boolean allInfo){
		List<BattleProto.CardsInfo> result = new ArrayList<BattleProto.CardsInfo>();
		for (FightCard fightCard : cardList) {
			BattleProto.CardsInfo.Builder cardsInfoBuilder = BattleProto.CardsInfo.newBuilder();
			cardsInfoBuilder.setId(fightCard.getId());
			if (allInfo) {
				cardsInfoBuilder.setCfgId(fightCard.getCfgId());
				cardsInfoBuilder.setAttack(fightCard.getAttack());
				cardsInfoBuilder.setHp(fightCard.getHp());
				cardsInfoBuilder.setMagic(fightCard.getMagic());
				cardsInfoBuilder.setSpeed(fightCard.getSpeed());
				cardsInfoBuilder.setType(PBConvertHelper.cardTypeConvert(fightCard.getCardType()));
			}
			result.add(cardsInfoBuilder.build());
		}
		return result;
	}
	/**
	 * action转换
	 * @param actions
	 * @return
	 */
	public static List<BattleProto.GeneralAct> toGeneralAct(List<Action> actions) {
		List<BattleProto.GeneralAct> result = new ArrayList<BattleProto.GeneralAct>();
		for (Action action : actions) {
			
			if (action instanceof AttackAction) {
				BattleProto.GeneralAct.Builder builder = BattleProto.GeneralAct.newBuilder();
				builder.setType(ActionType.ATTACK);
				builder.setAtkAct((BattleProto.AttackAction.Builder)action.toProtocolBufferBuilder());
				result.add(builder.build());
			} else if (action instanceof MagicChangeAction) {
				BattleProto.GeneralAct.Builder builder = BattleProto.GeneralAct.newBuilder();
				builder.setType(ActionType.ACTOR_MAGIC_CHANGE);
				builder.setMagicChangeAct((BattleProto.MagicChangeAction.Builder)action.toProtocolBufferBuilder());
				result.add(builder.build());
			} else if (action instanceof MomentAction) {
				BattleProto.GeneralAct.Builder builder = BattleProto.GeneralAct.newBuilder();
				builder.setType(ActionType.MOMENT);
				builder.setMomentAct((BattleProto.MomentAction.Builder)action.toProtocolBufferBuilder());
				result.add(builder.build());
			} else if (action instanceof ChooseCardAction) {
				BattleProto.GeneralAct.Builder builder = BattleProto.GeneralAct.newBuilder();
				builder.setType(ActionType.CHOOSE_CARD);
				builder.setChooseCardAct((BattleProto.ChooseCardAction.Builder)action.toProtocolBufferBuilder());
				result.add(builder.build());
			} else if (action instanceof CardToLocationAction) {
				BattleProto.GeneralAct.Builder builder = BattleProto.GeneralAct.newBuilder();
				builder.setType(ActionType.CARD_TO_LOCATION);
				builder.setCardToLocationAct((BattleProto.CardToLocationAction.Builder)action.toProtocolBufferBuilder());
				result.add(builder.build());
			} else if (action instanceof BatchAction) {
				BattleProto.GeneralAct.Builder builder = BattleProto.GeneralAct.newBuilder();
				builder.setType(ActionType.BACTH);
				builder.setBatchAct((BattleProto.BatchAction.Builder)action.toProtocolBufferBuilder());
				result.add(builder.build());
			} else if (action instanceof BuffAction) {
				BattleProto.GeneralAct.Builder builder = BattleProto.GeneralAct.newBuilder();
				builder.setType(ActionType.BUFF);
				builder.setBuffAct((BattleProto.BuffAction.Builder)action.toProtocolBufferBuilder());
				result.add(builder.build());
			} else if (action instanceof AttributeChangeAction) {
				BattleProto.GeneralAct.Builder builder = BattleProto.GeneralAct.newBuilder();
				builder.setType(ActionType.ATTRIBUTE);
				builder.setAttributeAct((BattleProto.AttributeChangeAction.Builder)action.toProtocolBufferBuilder());
				result.add(builder.build());
			} else if (action instanceof ChangeUnitAction) { 
				BattleProto.GeneralAct.Builder builder = BattleProto.GeneralAct.newBuilder();
				builder.setType(ActionType.CHANGE_UNIT);
				builder.setChangeUnitAct((BattleProto.ChangeUnitAction.Builder)action.toProtocolBufferBuilder());
				result.add(builder.build());
			} else if (action instanceof SkillAction){
				BattleProto.GeneralAct.Builder builder = BattleProto.GeneralAct.newBuilder();
				builder.setType(ActionType.SKILL);
				builder.setSkillAct((BattleProto.SkillAction.Builder)action.toProtocolBufferBuilder());
			} else if (action instanceof EndAction){
				BattleProto.GeneralAct.Builder builder = BattleProto.GeneralAct.newBuilder();
				builder.setType(ActionType.END);
				builder.setEndAct((BattleProto.EndAction.Builder)action.toProtocolBufferBuilder());
			} else {
				throw new RuntimeException("action not build:" + action.getClass());
			}
		}
		return result;
	}
	
	public static BattleProto.AttributeEntry.Attribute convertAttribute(FighterAttribute attribute) {
		for (BattleProto.AttributeEntry.Attribute att : BattleProto.AttributeEntry.Attribute.values()) {
			if(attribute.ordinal() == att.ordinal()) {
				return att;
			}
		}
		return BattleProto.AttributeEntry.Attribute.NONE;
	}
	public static BattleProto.EndAction.EndType convertEndType(EndType endType) {
		for (BattleProto.EndAction.EndType type : BattleProto.EndAction.EndType.values()) {
			if(endType.ordinal() == type.ordinal()) {
				return type;
			}
		}
		return BattleProto.EndAction.EndType.DRAW;
	}
	
	
	public static BattleProto.BattleDataResponse.Builder getBattleDataResponseBuilder(long actorId, BattleData bd) {
		BattleProto.BattleDataResponse.Builder builder = BattleProto.BattleDataResponse.newBuilder();
		Map<Long, ActorCard> actorCards = bd.getActorCards();
		for (Map.Entry<Long, ActorCard> entry : actorCards.entrySet()) {
			BattleProto.BattleDataResponse.ActorCard.Builder actorCardBuilder = BattleProto.BattleDataResponse.ActorCard.newBuilder();
			actorCardBuilder.setActorId(entry.getKey());
			ActorCard actorCard = entry.getValue();
			actorCardBuilder.setTeam(PBConvertHelper.teamConvert(actorCard.getTeam()));
			List<CardsInfo> sList = PBConvertHelper.fightCard2CardsInfo(actorCard.getStorageCards(), false);
			for (CardsInfo cardsInfo : sList) {
				actorCardBuilder.addStorageCards(cardsInfo);
			}
			if (actorId == entry.getKey()) {
				sList = PBConvertHelper.fightCard2CardsInfo(actorCard.getHandsCards(), true);
			} else {
				sList = PBConvertHelper.fightCard2CardsInfo(actorCard.getHandsCards(), false);
			}
			for (CardsInfo cardsInfo : sList) {
				actorCardBuilder.addHandsCards(cardsInfo);
			}
			sList = PBConvertHelper.fightCard2CardsInfo(actorCard.getDeskCards(), true);
			for (CardsInfo cardsInfo : sList) {
				actorCardBuilder.addDeskCards(cardsInfo);
			}
			sList = PBConvertHelper.fightCard2CardsInfo(actorCard.getHeroCards(), true);
			for (CardsInfo cardsInfo : sList) {
				actorCardBuilder.addHeroCards(cardsInfo);
			}
			actorCardBuilder.setCurrentMagic(actorCard.getCurrentMagic());
			actorCardBuilder.setMaxMagic(actorCard.getMaxMagic());
			builder.addCardStone(actorCardBuilder);
		}
		return builder;
	}
}
	
	
	
